import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;

/**
 * 定义服务端
 */
public class Server {
    //端口号
    private int port;

    public int getPort() {
        return port;
    }

    //主线程：mainReactor
    private Acceptor acceptor;
    //子线程： subReactor
    private Set<PollerIO> ioThreads;
    //线程池： 业务线程
    private ExecutorService buExecutor;

    //status flag 是否停止
    public volatile boolean stopped = false;


    //初始化方法
    public void init() {
        //todo 读取配置文件
        this.port=9999;
        //prepare io thread
        //初始化子线程数量，最少4个
        int ioNumbers=Math.max(4, Runtime.getRuntime().availableProcessors()*2);
        this.ioThreads=new HashSet<>(ioNumbers);
        for (int i = 0; i < ioNumbers; i++) {
            //根据线程池数量创建子线程，并将子线程加入到子线程集合中，this是当前线程，为了方便获取当前线程的状态
            PollerIO ioThread = new PollerIO("poller"+i,this);
            this.ioThreads.add(ioThread);
        }
        // prepare acceptor thread
        try {
            this.acceptor=new Acceptor("acceptor",this,this.ioThreads);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //开启
    public void start() {
        //start buExecutor 开启业务线程
        this.buExecutor=new ThreadPoolExecutor(
                50,
                100,
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(1000));
        //start io threads 开启子线程
        for (PollerIO ioThread : ioThreads) {
            ioThread.start();
        }
        //start acceptor thread 开启主线程
        this.acceptor.start();
    }
    //关闭
    public void shutdown() {
        this.stopped=true;
        this.buExecutor.shutdown();
    }


    public static void main(String[] args) {
        CountDownLatch latch=new CountDownLatch(1);

        Server server=new Server();
        server.init();
        server.start();

        Runtime.getRuntime().addShutdownHook(new Thread(()->{
            server.shutdown();
            latch.countDown();
        }));
        try {
            latch.await();
            System.out.println("server 退出");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


    }


    public void addBusTask(BuTask buTask) {
        this.buExecutor.execute(buTask);
    }
}
